import { getLodop } from '../utils/LodopFuncs.js'
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus'
import html2Canvas from 'html2canvas'
// import './lodop.scss'

export const lodopFn = (content: any, printType?: string, isManyTask?: boolean): any => {
  /**
   * 1、content---(设置打印的内容)对应的参数说明：
   *    三种方式[必须传--Array]：
   *    （1）、选择打印设计的模板名称方式：
   *        content =[
   *          {  innerHtml: '<div>...</div>'
   *             checkPrinter: ’xx‘,  模板选择打印的打印机器（配置模板有选项）
   *             paperConfig: {
   *               pageHeight: 纸张高度;
   *               pageWidth: 纸张宽度;
   *               pageName: 纸张类型;
   *               pageOrientation:打印纸张方向， 1：纵向， 2: 横向;
   *               pageNumberSite: 纸张页码显示位置以及是否显示（配置模板有选项）
   *               }
   *              }
   *        ];   一个节点的innerHTML字符串数组， 每个innerHTML代表需要去打印或者打印预览的html内容；
   *
   *    （2）、不选择模板，自定义传入base64图片打印
   *        content =[
   *          {  invoiceFile：'data:base64//xxxxxxxx'
   *             checkPrinter: ’xx‘, 模板选择打印的打印机器（配置模板有选项）
   *             paperConfig: {
   *               pageHeight: 纸张高度;
   *               pageWidth: 纸张宽度;
   *               pageName: 纸张类型;
   *               pageOrientation:打印纸张方向， 1：纵向， 2: 横向;
   *               pageNumberSite: 纸张页码显示位置以及是否显示, 不传默认显示右上角（自定义传惨，参数值：‘不显示’，‘右上角’，‘左上角’，‘右下角’，‘左下角’，‘正下方’）
   *               }
   *             },
   *        ]   // 参数是一个base64图片的数组， invoiceFile是字段名字
   *
   *    （3）、不选择模板，需要把节点转换成图片打印
   *        content =[
   *          { element: dom,
   *            checkPrinter: ’xx‘, 模板选择打印的打印机器（需要吧打印机的名称传过来）
   *               paperConfig: {
   *               pageHeight: 纸张高度;
   *               pageWidth: 纸张宽度;
   *               pageName: 纸张类型;
   *               pageOrientation:打印纸张方向， 1：纵向， 2: 横向;
   *               pageNumberSite: 纸张页码显示位置以及是否显示, 不传默认显示右上角（自定义传惨，参数值：‘不显示’，‘右上角’，‘左上角’，‘右下角’，‘左下角’，‘正下方’）
   *               }
   *             }
   *        ];  // 参数是dom的节点名字
   *
   *
   *---------------------------------------------------------------------------------------------------------------------
   * 2、printType---对应的参数说明：
   *    printType(选--String)： 判断打印还是打印预览(printPreview: 打印预览；print：直接打印)；
   *                            不传默认是print直接打印；
   *
   *
   * --------------------------------------------------------------------------------------------------------------------
   * 3、isManyTask: 判断是单任务/单任务多页，还是多任务; 参数为布尔值，可以不传，不传或者false全部走多任务，true走单任务及单任务多页
   *    注意：传不传并不影响去执行打印， 主要是为了打印预览， 单任务多页预览可以预览下一页的内容，多任务是不支持预览第二个打印的内容，只可预览第一个打印的内容！
   *
   */
  console.log(content)

  let _LODOP: any,
    P_ID: string = '',
    TaskID1: any,
    TaskID2: any,
    t: any,
    c: number = 0,
    printNameList: any = [] //声明为全局变量

  // 获取lodop对象
  _LODOP = getLodop()

  // 校验打印机是否安装 如未安装 则去安装
  if (!_LODOP) {
    // 如未安装打印控件，提示用户安装
    ElMessageBox.confirm('未安装打印控件！是否安装打印控件？安装后请刷新页面！', '打印提示', {
      confirmButtonText: '下载',
      cancelButtonText: '取消',
      type: 'warning',
      closeOnClickModal: false,
    })
      .then(() => {
        window.location.href = `${window.location.origin}/pic/CLodopSetup.exe`
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '已取消下载, 未安装打印控件不可打印预览！',
        })
      })
    return false
  }

  // 获取当前电脑的打印机个数
  let getPrinterCount = () => {
    return _LODOP.GET_PRINTER_COUNT()
  }
  // 获取本地打印机的名称
  for (let i = 0; i < getPrinterCount(); i++) {
    printNameList.push(_LODOP.GET_PRINTER_NAME(i))
  }

  // 配置loading
  ElLoading.service({
    text: '正在加载打印或打印预览内容, 请稍后...',
  })

  let WaitFor = () => {
    c = c + 1
    t = setTimeout('WaitFor()', 1000)
    if (_LODOP.GET_VALUE('PRINT_STATUS_OK', P_ID)) {
      clearTimeout(t)
      c = 0
      ElMessage({
        type: 'info',
        message: '打印成功!',
      })
      window.localStorage.isPrint = '成功'
    }
    if (!_LODOP.GET_VALUE('PRINT_STATUS_EXIST', P_ID) && c > 0) {
      clearTimeout(t)
      c = 0
      ElMessage({
        type: 'info',
        message: '打印任务被删除!',
      })
      return false
    } else if (c > 30) {
      clearTimeout(t)
      c = 0
      ElMessage({
        type: 'info',
        message: '打印超过30秒没捕获到成功状态!',
      })
      window.localStorage.isPrint = '失败'
    }
  }

  let C_WaitFor = () => {
    c = c + 1
    t = setTimeout('C_WaitFor()', 1000)
    _LODOP.On_Return_Remain = true
    _LODOP.On_Return = function (TaskID: any, Value: any) {
      if (TaskID == TaskID1) {
        if (Value == 1) {
          clearTimeout(t)
          c = 0
          ElMessage({
            type: 'info',
            message: '打印成功！',
          })
          window.localStorage.isPrint = '成功'
          // 调用的组件中使用
          // var timer = setInterval(()=> {
          //   if(!!window.localStorage.isPrint) {
          //     保存 window.localStorage.isPrint的值(不管成功还是失败)， 记录打印是否成功了;
          //     保存之后再删除，并且清楚定时器
          //     window.localStorage.removeItem('isPrint')
          //     clearInterval(timer);
          //   }
          // }, 1000);
        }
      }
    }
    TaskID1 = _LODOP.GET_VALUE('PRINT_STATUS_OK', P_ID)
    TaskID2 = _LODOP.GET_VALUE('PRINT_STATUS_EXIST', P_ID)
    if (c > 50) {
      clearTimeout(t)
      c = 0
      ElMessage({
        type: 'info',
        message: '打印超过50秒没捕获到成功状态!',
      })
      window.localStorage.isPrint = '失败'
    }
  }

  // 设置打印纸张的大小
  let _setPaper = (obj: any) => {
    if (!!obj && !!obj.paperConfig) {
      let _config = obj.paperConfig
      // 设置纸张大小 打印方向以及自定义的纸张
      if (!!_config && !!_config.pageOrientation && !!_config.pageName) {
        if (_config.pageName == 'custom') {
          _LODOP.SET_PRINT_PAGESIZE(_config.pageOrientation, _config.pageWidth + 'mm', _config.pageHeight + 'mm', '')
        } else {
          _LODOP.SET_PRINT_PAGESIZE(_config.pageOrientation, 0, 0, _config.pageName)
        }
      }
    } else {
      _LODOP.SET_PRINT_PAGESIZE(1, '210mm', '297mm', 'A4')
    }
  }

  // 判断是打印预览还是直接打印
  let _printType = () => {
    _LODOP.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
    if (_LODOP.CVERSION) {
      _LODOP.On_Return = (TaskID: any, Value: any) => {
        P_ID = Value
        //  console.log("该任务走的是c-lodop方式，job代码为"+P_ID);
        if (P_ID != '') {
          c = 0
          C_WaitFor()
        }
      }
      if (!!printType && printType == 'printPreview') {
        _LODOP.PREVIEW()
      } else {
        _LODOP.PRINT()
      }
    } else {
      // P_ID=_LODOP.PRINTA();
      P_ID = _LODOP.PRINT()
      // P_ID = !!printType && printType == 'printPreview' ? _LODOP.PREVIEW() : _LODOP.PRINT()
      if (P_ID != '') {
        c = 0
        WaitFor()
      }
    }
  }

  // 设置打印的页码
  let _setPageNumber = (flag: any) => {
    // 打印图片直接返回不设置页码
    if (!!flag.invoiceFile) return
    // 打印页码(模板不设置，默认展示在右上角)
    if (!!flag && !!flag.paperConfig && !!flag.paperConfig.pageNumberSite) {
      if (flag.paperConfig.pageNumberSite != '不展示') {
        if (flag.paperConfig.pageNumberSite == '左上角') {
          _LODOP.ADD_PRINT_TEXT(20, 20, 150, 22, '第#页/共&页')
        } else if (flag.paperConfig.pageNumberSite == '右下角') {
          _LODOP.ADD_PRINT_TEXT('98%', '85%', 150, 22, '第#页/共&页')
        } else if (flag.paperConfig.pageNumberSite == '左下角') {
          _LODOP.ADD_PRINT_TEXT('98%', 20, 150, 22, '第#页/共&页')
        } else if (flag.paperConfig.pageNumberSite == '正下方') {
          _LODOP.ADD_PRINT_TEXT('98%', '47%', 150, 22, '第#页/共&页')
        } else {
          _LODOP.ADD_PRINT_TEXT(20, '85%', 150, 22, '第#页/共&页')
        }
      }
    } else {
      _LODOP.ADD_PRINT_TEXT(20, '85%', 150, 22, '第#页/共&页')
    }
    // _LODOP.ADD_PRINT_TEXT(20, '85%', 150, 22, '第#页/共&页')
    _LODOP.SET_PRINT_STYLEA(0, 'FontSize', 11)
    _LODOP.SET_PRINT_STYLEA(0, 'ItemType', 2)
  }

  // 打印机选择
  let _checkPrinter = (flag: any) => {
    // 指定打印机(如果没有指定打印机，选择默认打印机)
    if (!!flag) {
      // 模板配置了打印机，判断本地有没有该打印机
      console.log(printNameList, flag)
      if (!!printNameList) {
        if (printNameList.includes(flag)) {
          console.log('单任务走的指定打印机:', flag)
          _LODOP.SET_PRINTER_INDEX(flag)
        } else {
          console.log('单任务走的默认打印-情况3')
          _LODOP.SET_PRINTER_INDEX(-1)
        }
      } else {
        console.log('单任务走的默认打印-情况2')
        _LODOP.SET_PRINTER_INDEX(-1)
      }
    } else {
      console.log('单任务走的默认打印机-情况1')
      _LODOP.SET_PRINTER_INDEX(-1)
    }
  }

  let _clearLoadig = () => {
    // 消除loading
    const loadingInstance = ElLoading.service()
    loadingInstance.close()
  }

  // 创建要打印或者打印预览的所有内容
  let _createAllPages = (flag?: any): void => {
    let printData = !!flag ? flag : content
    // 消除loading
    _clearLoadig()
    // 获取整个项目head的文件
    let printContent = document.getElementsByTagName('head')[0].innerHTML

    // 判断是不是多任务打印； 默认情况走多任务打印
    if (isManyTask == undefined || !isManyTask) {
      // 多任务打印或者预览
      // 循环要打印的内容
      for (let i = 0; i < printData.length; i++) {
        // 初始化打印不同的任务名
        _LODOP.PRINT_INIT('lodop打印任务' + i)
        // 设置显示模式（显示模式的名称， 显示模式的值）
        _LODOP.SET_SHOW_MODE('LANDSCAPE_DEFROTATED', 1)
        // 控制位置基点
        _LODOP.SET_PRINT_MODE('POS_BASEON_PAPER', true)
        // 设置纸张大小 打印方向以及自定义的纸张
        _setPaper(printData[i])
        // 指定打印机(如果没有指定打印机，选择默认打印机)
        _checkPrinter(printData[i].checkPrinter)
        // 设置打印的内容
        // 判断是打印内容还是直接打印图片
        if (!!printData[i].innerHtml) {
          _LODOP.ADD_PRINT_HTM(0, 0, '100%', '100%', '<!DOCTYPE html>' + printContent + printData[i].innerHtml)
        } else {
          _LODOP.ADD_PRINT_IMAGE(0, 0, '100%', '100%', !!printData[i].invoiceFile ? printData[i].invoiceFile : printData[i].url)
        }
        // 设置分页
        _LODOP.NewPageA()
        //设置上面打印项延迟
        _LODOP.SET_PRINT_STYLEA(0, 'HtmWaitMilSecs', 1000)
        // 打印页码
        _setPageNumber(printData[i])
        // 判断打印预览还是直接打印
        console.log('唤醒lodop,等待lodop响应')
        _printType()
      }
    } else {
      // 初始化打印不同的任务名
      _LODOP.PRINT_INIT('lodop打印任务')
      // 设置显示模式（显示模式的名称， 显示模式的值）
      _LODOP.SET_SHOW_MODE('LANDSCAPE_DEFROTATED', 1)
      // 控制位置基点
      _LODOP.SET_PRINT_MODE('POS_BASEON_PAPER', true)
      // 设置纸张大小 打印方向以及自定义的纸张
      _setPaper(printData[0])
      // 指定打印机(如果没有指定打印机，选择默认打印机)
      _checkPrinter(printData[0].checkPrinter)
      // 循环要打印的内容(存在单任务分页情况)
      for (let i = 0; i < printData.length; i++) {
        // 设置打印的内容
        // 判断是打印内容还是直接打印图片
        if (!!printData[i].innerHtml) {
          _LODOP.ADD_PRINT_HTM(0, 0, '100%', '100%', '<!DOCTYPE html>' + printContent + printData[i].innerHtml)
        } else {
          _LODOP.ADD_PRINT_IMAGE(0, 0, '100%', '100%', !!printData[i].invoiceFile ? printData[i].invoiceFile : printData[i].url)
        }
        // 设置分页
        _LODOP.NewPageA()
        //设置上面打印项延迟
        _LODOP.SET_PRINT_STYLEA(0, 'HtmWaitMilSecs', 1000)
        // 打印页码
        _setPageNumber(printData[i])
      }
      // 判断打印预览还是直接打印
      console.log('唤醒lodop,等待lodop响应')
      _printType()
    }
  }

  if (c > 0) {
    ElMessage({
      type: 'info',
      message: '正在打印中...',
    })
    return
  }

  if (_LODOP.webskt && _LODOP.webskt.readyState == 1) {
    // 判断选择哪种打印和打印图片
    if (!content[0].element) {
      // ---- 选择的模板进行打印
      setTimeout((): void => {
        _createAllPages()
      }, 500)
      // _createAllPages()
    } else {
      let DPR = () => {
        // 获取设备dpi
        if (window.devicePixelRatio && window.devicePixelRatio > 1) {
          return window.devicePixelRatio
        }
        return 1
      }

      // 存放打印的图片
      let imgArr: any = []

      // 要打印或者打印预览的所有需要把节点内容转成图片格式的
      for (let obj of content) {
        const dom: CSSStyleDeclaration = window.getComputedStyle(obj.element)
        // DOM 节点计算后宽高
        const width: number = parseInt(dom.width, 10)
        const height: number = parseInt(dom.height, 10)
        // 获取像素比
        const scaleBy: number = DPR()
        // 创建自定义 canvas 元素
        const canvas: HTMLCanvasElement = document.createElement('canvas')
        // 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
        canvas.width = width * scaleBy
        canvas.height = height * scaleBy
        // 设定 canvas css宽高为 DOM 节点宽高
        canvas.style.width = `${width}px`
        canvas.style.height = `${height}px`
        // 获取画笔
        const context: any = canvas.getContext('2d')
        // 将所有绘制内容放大像素比倍
        context.scale(scaleBy, scaleBy)
        // 将自定义 canvas 作为配置项传入，开始绘制
        ;(function (c) {
          html2Canvas(obj.element, {
            canvas,
            useCORS: true,
            scale: 1 / scaleBy,
            allowTaint: true,
            // dpi: 300,
          }).then((imgDom) => {
            obj.url = imgDom.toDataURL('image/png', 1.0)
            imgArr.push(obj)
          })
        })(obj.element)
      }
      // 开始计时，如果dom画图成功之后，立即执行打印，消除定时
      var timer: number = setInterval(() => {
        if (content.length == imgArr.length) {
          // dom转成图片完成后，清楚定时器，并开始执行打印或者打印预览
          clearInterval(timer)
          // let img = document.createElement('img')
          // img.src = imgArr[0].url
          // document.body.appendChild(img)
          _createAllPages(imgArr)
        }
      }, 200)
    }
  } else {
    alert('打印没有备好， 需重新启动lodop或重启电脑!!')
  }
}
